A r t i c l e s
Navigation

Note: This site is
a bit older, personal views
may have changed.

M a i n P a g e

D i r e c t o r y

Arrays of Procedures and Functions


Tips on using arrays of procedures, and arrays of functions. Arrays of procedures and functions may seem bizarre to you. But they do come useful in some very important situations in advanced software programming. One area where they can be used is plug-in based software. Imagine that you have to import 40 different initialization procedures for 40 different plug-ins that are going to be loaded on the fly. Using setlength, you don't even have to know ahead of time that you have 40 different plug-ins in your /program/extras/plugin/ directory.

If each of your 40 plug-ins have all the same style of initilization procedures, each procedure is going to have the same syntax. So using an array of the procedure offers you access to the same style of procedures, but each procedure internal code being a bit different. Each plug in may have his own inititialization procedure.. not all plug in's want to fire off the same initialization code.


The real power of array's of functions and procedures are the fact that:
 -you can access them all at once in a loop
 -you can keep track of how many procedures by finding the length of your array
 -you can dynamically import or create more functions by using setlength, without 
  worrying about any limits. You couldn't do this with fixed single procedures.
 -if using arrays of procedures/functions in a plug-in system, no multiple calls to 
  GetProcAddress (GetProcAddr) are required to address similar functions in different 
  dynamic link libraries. Just grab all the imported procedures into an array of 
   procedures. Importing similar functions from different DLL's means you must use 
   procaddress excessively.
Knowing that you can have an array of procedures or functions is useful - but you may not immediatly see the need for them.
Here is how you access and fire off a procedure that is held in an array:

type
  TMyProc = procedure(s: string);
var
  MyProcArray: array of TMyProc;

begin
  setlength(MyProcArray,2);
  MyProcArray[0]('testing');
  MyProcArray[1]('test');
end;

OR

type
  TMyProc = procedure(s: string);
var
  MyProcArray: array [0..1] of TMyProc;

begin
  MyProcArray[0]('testing');
  MyProcArray[1]('test');
end;

OR
if you are loading a bunch of functions from a library (DLL or SO)

type
  TMyProc = procedure(s: string);stdcall;
var
  MyProcArray: array of TMyProc;
  MyLibHandle: THandle;
begin
  MyLibHandle:= LoadLibrary('MyLib.dll'); //or MyLib.so
  setlength(MyProcArray,2);
  MyProcArray[0]('testing'); //launches procedure stored in array
  MyProcArray[1]('test');    
end;

Interesting syntax? Definitely.. but it works just as you thought it would.


This below may cause access violation in freepascal:
type
  TMyProc = procedure(s: string);stdcall;
var
  MyProcArray: array of TMyProc;
  MyLibHandle: THandle;
begin
  MyLibHandle:= LoadLibrary('MyLib.dll'); //or MyLib.so
  setlength(MyProcArray,2);
  MyProcArray[0]('testing'); //this causes run time error on program closing 
  MyProcArray[1]('test');  //this causes access violation
  FreeLibrary(MyLibHandle);  
end;

(Bug reported in July 2005, may be fixed soon)

Subject: Array of procedure, Array of function, array of procedures, array of functions, multiple procedures, multiple functions.

About
This site is about programming and other things.
_ _ _